CallGraph
DotWriter.cpp
Go to the documentation of this file.
00001 #include "dotwriter.h"
00002 #include <wx/strconv.h>
00003 #include <wx/file.h> 
00004 #include <wx/msgdlg.h> 
00005 #include <wx/math.h>
00006 #include <math.h>
00007 
00008 
00009 DotWriter::DotWriter()
00010 {
00011         begin_graph = wxT("digraph\n{");
00012         end_graph = wxT("}\n");
00013         fontname = wxT("Arial");
00014         style = wxT("filled");
00015         shape = wxT("box");
00016         cwhite = wxT("white");
00017         cblack = wxT("black");
00018         hnode = wxT("");
00019         dedge = wxT("");
00020         hedge = wxT("");
00021         dlabel = wxT("");
00022         graph = wxT("");
00023         output = wxT("");
00024         mlines = NULL;
00025         m_mgr = NULL;
00026         dwcn = 0;
00027         dwce = 0;
00028         dwtn = 0;
00029         dwte = 0;
00030         dwbname = false;
00031         dwbparam = false;
00032         writedotfile = false;
00033 }
00034 
00035 DotWriter::~DotWriter()
00036 {
00037         
00038 }
00039 
00040 void DotWriter::setLineParser(LineParserList *pLines )//, int numOfLines)
00041 {
00042         mlines = pLines;
00043 }
00044 
00045 void DotWriter::setDotWriterFromDialogSettings(IManager *mgr)
00046 {
00047         m_mgr = mgr;
00048         m_mgr->GetConfigTool()->ReadObject(wxT("CallGraph"), &confData);
00049         dwcn = confData.GetColorsNode();
00050         dwce = confData.GetColorsEdge();
00051         dwtn = confData.GetTresholdNode();
00052         dwte = confData.GetTresholdEdge();
00053         dwbname = confData.GetBoxName();
00054         dwbparam = confData.GetBoxParam();
00055 }
00056 
00057 
00058 void DotWriter::WriteToDotLanguade()
00059 {
00060         int pl_index = 0;
00061         float pl_time = 0;
00062         bool is_node = false;
00063         wxArrayInt index_pl_nodes;
00064         
00065         if (mlines == NULL)
00066                 return;
00067                 
00068         graph = wxT("graph [ranksep=\"0.25\", fontname=") + fontname + wxT(", nodesep=\"0.125\"];");
00069         
00070         hnode = wxT("node [label=\"\\N\", fontname=") + fontname + wxT(", style=") + style + wxT(", height=0, width=0, shape=") + shape + wxT(", fontcolor=") + cwhite + wxT("];");
00071 
00072         hedge = wxT("edge [fontname=") + fontname + wxT("];");
00073 
00074         //graph []; -- not used
00075         
00076         output += begin_graph + wxT("\n") + graph + wxT("\n") + hnode + wxT("\n") + hedge + wxT("\n");
00077         
00078         LineParserList::compatibility_iterator it = mlines->GetFirst();
00079         
00080         while(it)
00081         {
00082                 LineParser *line = it->GetData();
00083         
00084                 //if (line->name.IsEmpty()) break;
00085                 
00086                 if(line->pline && wxRound(line->time) >= dwtn)
00087                 {
00088                         is_node = true;
00089                         index_pl_nodes.Add(line->index);
00090                         dlabel = wxString::Format(wxT("%i"),line->index); 
00091                         dlabel += wxT(" [label=\"");
00092                         dlabel += OptionsShortNameAndParameters(line->name);
00093                         dlabel += wxT("\\n");
00094                         dlabel += wxString::Format(wxT("%.2f"), line->time);
00095                         dlabel += wxT("% \\n");
00096                         dlabel += wxT("(");
00097                         dlabel += wxString::Format(wxT("%.2f"), line->self); 
00098                         dlabel += wxT("%)");
00099                         dlabel += wxT("\\n");
00100                         if(line->called0 != -1)
00101                                 dlabel += wxString::Format(wxT("%i"),line->called0) + wxT("x");
00102                         //if(line->recursive)   
00103                         //      dlabel += wxT(" (") + wxString::Format(wxT("%i"),line->called0 + line->called1) + wxT("x)");
00104                         dlabel += wxT("\",fontcolor=\"");
00105                         dlabel += DefineColorForLabel(ReturnIndexForColor(line->time, dwcn));
00106                         dlabel += wxT("\", color=\"");
00107                         dlabel += DefineColorForNodeEdge(ReturnIndexForColor(line->time, dwcn));
00108                         //
00109                         dlabel += wxT("\", fontsize=\"12.00\"];");
00110                         //
00111                         output += dlabel + wxT("\n");
00112                         //
00113                         dlabel.Clear();
00114                 }
00115                 it = it->GetNext();
00116         }
00117         
00118         it = mlines->GetFirst();
00119         
00120         while(it)
00121         {
00122                 LineParser *line = it->GetData();
00123                 
00124                 if(line->pline)
00125                 {
00126                         pl_index = line->index; // index for primary node
00127                         pl_time = line->time; // time for primary node
00128                 }
00129                 
00130                 if (line->child && IsInArray(line->nameid,index_pl_nodes) && IsInArray(pl_index,index_pl_nodes) && (wxRound(pl_time) >= dwte))
00131                 {
00132                         dedge = wxString::Format(wxT("%i"), pl_index);
00133                         dedge += wxT(" -> ");
00134                         dedge += wxString::Format(wxT("%i"),line->nameid);
00135                         dedge += wxT(" [color=\"");
00136                         dedge += DefineColorForNodeEdge(ReturnIndexForColor(pl_time, dwce)); // color by primary node
00137                         dedge += wxT("\", label=\"");
00138                         //if(line->self != -1)
00139                         //dedge += wxString::Format(wxT("%.2f"),line->self) + wxT("%");
00140                         //dedge += wxT("\\n");
00141                         dedge += wxString::Format(wxT("%i"),line->called0);
00142                         dedge += wxT("x"); 
00143                         dedge += wxT("\" ,arrowsize=\"0.50\", fontsize=\"10.00\", fontcolor=\"");
00144                         dedge += cblack;
00145                         dedge += wxT("\", penwidth=\"2.00\"];"); // labeldistance=\"4.00\",                     
00146                         //
00147                         output += dedge + wxT("\n");
00148                         //
00149                         dedge.Clear();          
00150                 }
00151                 it = it->GetNext();
00152         }
00153         output += end_graph;
00154         
00155         if (!is_node) // if the call graph is empty create new graph with label node
00156         {        
00157                 output = wxT("digraph e {0 [label=");
00158                 output += wxT("\"Call Graph is empty, please check settings of node resolutions for this plugin!\"");
00159                 output += wxT(", shape=none, height=2, width=2, fontname=Arial, fontsize=14.00];}");
00160         }
00161 }
00162 
00163 void DotWriter::SendToDotAppOutputDirectory(wxString apppathfolder)
00164 {
00165         wxString dotfilespath = apppathfolder + stvariables::dotfilesdir + stvariables::sd;
00166         wxString dottxtpath = dotfilespath + stvariables::dottxtname;
00167         if(!wxDirExists(dotfilespath))
00168         {
00169                 wxMkdir(dotfilespath.c_str());
00170         }
00171         
00172         if (wxFileExists(dottxtpath))
00173                 wxRemoveFile(dottxtpath);       
00174         
00175         //create new txt file   
00176         wxFile pFile(dottxtpath, wxFile::write);
00177         pFile.Open(dottxtpath, wxFile::write);
00178         
00179         if(pFile.IsOpened()) 
00180         {
00181                 writedotfile = pFile.Write(output);
00182                 pFile.Close();
00183         }
00184         else
00185         {
00186                 return;
00187         }
00188 }
00189 
00190 bool DotWriter::DotFileExist(wxString apppathfolder)
00191 {
00192         wxString dotfilespath = apppathfolder + stvariables::dotfilesdir + stvariables::sd + stvariables::dottxtname;
00193         
00194         if (wxFileExists(dotfilespath) && writedotfile) 
00195                 return true;
00196                 else return false;      
00197 }
00198 
00199 wxString DotWriter::OptionsShortNameAndParameters(wxString name)
00200 {
00201         if (name.Contains(wxT('(')) && name.Contains(wxT(')')) && dwbname)
00202         {
00203                 wxString out = name.BeforeFirst(wxT('('));
00204                 out += wxT("()"); // for function return just ()
00205                 return out;
00206         
00207         }
00208         else if (name.Contains(wxT('(')) && name.Contains(wxT(')')) && dwbparam)
00209         {
00210                 wxString out = name.BeforeFirst(wxT('('));
00211                 wxString sub = name.AfterFirst(wxT('(')).BeforeFirst(wxT(')'));
00212                 if (sub.IsEmpty())
00213                 {
00214                         out += wxT("\\n(\\n)");
00215                         return out;
00216                 }
00217                 else if(sub.Contains(wxT(",")))
00218                 {
00219                         sub.Replace(wxT(","), wxT(",\\n"));
00220                         out += wxT("\\n(\\n") + sub + wxT("\\n)");
00221                         return out;
00222                 }
00223                 else
00224                 {
00225                         out += wxT("\\n(\\n") + sub + wxT("\\n)");
00226                         return out;
00227                 
00228                 }
00229         }
00230         else return name;
00231 }
00232 
00233 int DotWriter::ReturnIndexForColor(float time, int dwc)
00234 {
00235         int index = 0;
00236         struct BarvaRozsah
00237         {
00238                 int dolniIndex;
00239                 int horniIndex;       
00240                 int indexBarvy;
00241         };
00242         
00243         BarvaRozsah *barvyVybrane;
00244         barvyVybrane = new BarvaRozsah[dwc];
00245         
00246         if(dwc == 1)
00247     {
00248      barvyVybrane[0].dolniIndex = 0;
00249      barvyVybrane[0].horniIndex = 100;
00250      barvyVybrane[0].indexBarvy = 0;
00251     }
00252     else if(dwc == 2)
00253     {
00254      barvyVybrane[0].dolniIndex = 0;
00255      barvyVybrane[0].horniIndex = 50;
00256      barvyVybrane[0].indexBarvy = 0;
00257      barvyVybrane[1].dolniIndex = 51;
00258      barvyVybrane[1].horniIndex = 100;
00259      barvyVybrane[1].indexBarvy = 9;
00260     }
00261     else if(dwc > 2 && dwc < 11)
00262     {
00263         int pocetIntervalu = dwc-1;
00264         float krokIntervalu = 8.0/(float)pocetIntervalu;
00265         float delkaIntervalu = 100.0/(float)dwc;
00266         delkaIntervalu = round(delkaIntervalu);
00267         int poModulu = 8 % pocetIntervalu;
00268         float zbytekPripocet = (float)poModulu/pocetIntervalu;
00269         float pripocitat = 0.0;
00270         
00271                 for(int i=0; i<dwc; i++)
00272                 {
00273                         pripocitat += zbytekPripocet;
00274                         if(i==0)
00275                         {
00276                         barvyVybrane[i].dolniIndex = 0;
00277                         barvyVybrane[i].horniIndex = (int)delkaIntervalu;
00278                         barvyVybrane[i].indexBarvy = 0;       
00279                         }        
00280                         else if(i==(dwc-1))
00281                         {
00282                         barvyVybrane[i].dolniIndex = barvyVybrane[i-1].horniIndex+1;
00283                         barvyVybrane[i].horniIndex = 100;
00284                         barvyVybrane[i].indexBarvy = 9;       
00285                         }
00286                         else if(i>0 && i<(dwc-1))
00287                         {
00288                                 int pripocet = 0;
00289                                 if(0.8 < pripocitat && pripocitat < 1.2)
00290                                 {
00291                                         pripocet = 1;
00292                                         pripocitat = 0;
00293                                 }
00294                                 barvyVybrane[i].dolniIndex = barvyVybrane[i-1].horniIndex + 1;
00295                                 barvyVybrane[i].horniIndex = barvyVybrane[i-1].horniIndex + (int)delkaIntervalu;
00296                                 barvyVybrane[i].indexBarvy = (int)round((float)barvyVybrane[i-1].indexBarvy + krokIntervalu) + pripocet;  
00297                         }       
00298                 }
00299         }
00300         
00301         for(int i=0; i<dwc; i++)
00302         {
00303                 if ((int)barvyVybrane[i].dolniIndex <= (int)time && (int)time <= (int)barvyVybrane[i].horniIndex)
00304                 {
00305                         index = (int)barvyVybrane[i].indexBarvy;
00306                         break;
00307                 }
00308         }
00309         return index;
00310 }
00311 
00312 wxString DotWriter::DefineColorForNodeEdge(int index)
00313 {
00314         wxString colors[10] = {wxT("#006837"), wxT("#1a9850"), wxT("#66bd63"), wxT("#a6d96a"), wxT("#d9ef8b"), wxT("#fee08b"), wxT("#fdae61"), wxT("#f46d43"), wxT("#d73027") ,wxT("#a50026")};
00315         return colors[index];
00316 }
00317 
00318 bool DotWriter::IsInArray(int index, wxArrayInt arr)
00319 {
00320         for(unsigned int i = 0; i < arr.GetCount(); i++)
00321         {
00322                 if (arr.Item(i) == index) return true;
00323         }
00324         return false;
00325 
00326 }
00327 
00328 wxString DotWriter::DefineColorForLabel(int index)
00329 {
00330         if ((index < 3) || (index > 6))
00331         {
00332                 return cwhite;
00333         }
00334         else
00335         {
00336                 return cblack;
00337         }
00338 }
 All Classes Files Functions Variables